package com.TocaLetras;


import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.EmbossMaskFilter;
import android.graphics.MaskFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Chronometer;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class JuegoPrincipalActivity extends Activity  implements ColorPickerDialog.OnColorChangedListener{
	
	private final int SECONDARY_ACTIVITY_REQUEST_CODE=0;
	private final int tamanio_celda=50;
	private final int tamanio_trazo=50;
	
	private ImageButton Btn_salir;
	private Chronometer Cronometro;
	
	private TextView TxtX;
	private TextView TxtY;
	private TextView Txtcont;
	
	private ImageView Figura;
	private boolean Reiniciar = false;
	private final String Limite_tiempo ="10";
	private int Contador =0;
	
	private Paint mPaint;
	private Paint mCirPaint;
	private Paint mPtrazo;
	private Paint mP;
	
	private MaskFilter  mEmboss;
	private MaskFilter  mBlur;
	private ViewGroup lienzo_dibujo ;
	
	private ArrayList<Point> MisPuntos = new ArrayList<Point>();
	private ArrayList<Point> PuntosLetras = new ArrayList<Point>();
	private ArrayList<MyPunto> Trazo = new ArrayList<MyPunto>();
	
	
	//metodo llamado cuando se crea el activity
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.principal);
        iniciar();
        addListeners();
        //colocar el lienzo
        lienzo_dibujo =   (ViewGroup) findViewById(R.id.lienzo);
        lienzo_dibujo.addView(new MyView(this));
        
        //Representa el pincel , permite definir color y tipo de trazado
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(0xFFFF0000); //seteamos el color en rojo
        mPaint.setStyle(Paint.Style.STROKE);//estilo del trazado
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(12);// grosor de trazado
        
        mCirPaint = new Paint();
        mCirPaint.setAntiAlias(true);
        mCirPaint.setDither(true);
        mCirPaint.setColor(Color.BLUE); //seteamos el color en rojo
        mCirPaint.setStyle(Paint.Style.FILL);//estilo del trazado
        mCirPaint.setStrokeJoin(Paint.Join.ROUND);
        mCirPaint.setStrokeCap(Paint.Cap.ROUND);
        mCirPaint.setStrokeWidth(6);// grosor de trazado
        
        mPtrazo = new Paint();
        mPtrazo.setAntiAlias(true);
        mPtrazo.setDither(true);
        mPtrazo.setColor(Color.WHITE); //seteamos el color en rojo
        mPtrazo.setStyle(Paint.Style.STROKE);//estilo del trazado
        mPtrazo.setStrokeJoin(Paint.Join.ROUND);
        mPtrazo.setStrokeCap(Paint.Cap.ROUND);
        mPtrazo.setStrokeWidth(1);// grosor de trazado
        
        mP = new Paint();
        mP.setAntiAlias(true);
        mP.setDither(true);
        mP.setColor(Color.WHITE); //seteamos el color
        mP.setStyle(Paint.Style.FILL);//estilo del trazado
        mP.setStrokeJoin(Paint.Join.ROUND);
        mP.setStrokeCap(Paint.Cap.ROUND);
        mP.setStrokeWidth(1);// grosor de trazado
        
        

        mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },0.4f, 6, 3.5f);
        mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
    }
	
	//metodo llamado cuando se regresa al activity
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	super.onActivityResult(requestCode,resultCode,data);
    	
		this.Cronometro.setBase(SystemClock.elapsedRealtime());
		Reiniciar=false;
		}
	
	//permite inicializar los componentes de la pantalla
	public void iniciar(){
		Btn_salir = (ImageButton)findViewById(R.id.btn_principal_salir);
		Txtcont = (TextView) this.findViewById(R.id.txt_principal_contador);
		actualizarContador();
	   	Cronometro = (Chronometer) findViewById(R.id.chronometer1);
	    //Cronometro.start();
	    TxtX = (TextView) findViewById(R.id.txt_puntox);
	    TxtY = (TextView) findViewById(R.id.txt_puntoy);
	    
	    /*untosLetras.add(new Point((int)275.0 , (int)75.0));
	    PuntosLetras.add(new Point((int)225.0 , (int)75.0));
	    PuntosLetras.add(new Point((int)175.0 , (int)75.0));
	    
	  
	    
	    
	    PuntosLetras.add(new Point((int)125.0 , (int)75.0));
	    
	    PuntosLetras.add(new Point((int)125.0 , (int)125.0));
	    PuntosLetras.add(new Point((int)125.0 , (int)175.0));
	    PuntosLetras.add(new Point((int)125.0 , (int)225.0));
	    
	    PuntosLetras.add(new Point((int)125.0 , (int)275.0));
	    
	   
	    
	    PuntosLetras.add(new Point((int)275.0 , (int)325.0));
	    PuntosLetras.add(new Point((int)225.0 , (int)325.0));
	    PuntosLetras.add(new Point((int)175.0 , (int)325.0));*/
	    
	    //PuntosLetras=Util.puntosC();
	    
	    //Trazo = Util.generarPuntosLetraC();
	    
	    PuntosLetras=Util.puntosP();
	    
	    Trazo = Util.trazoP();
	    
	}
	
	public void dibujarMalla(Canvas c){
		for(int i=0; i<=360; i+=tamanio_celda){
			for(int j=0; j<=420; j+=tamanio_celda){
				c.drawRect(i,j,i+tamanio_celda,j+tamanio_celda,this.mPtrazo);
			}
		}
	}
	
	public void dibujarTrazo(Canvas c){
		for(MyPunto p: Trazo){
			if(!p.isVisitado()){
				this.mP.setColor(Color.WHITE);
				c.drawRect(p.x*tamanio_trazo,p.y*tamanio_trazo,p.x*tamanio_trazo+tamanio_trazo,p.y*tamanio_trazo+tamanio_trazo, this.mP);
			}else{
				this.mP.setColor(Color.GREEN);
				c.drawRect(p.x*tamanio_trazo,p.y*tamanio_trazo,p.x*tamanio_trazo+tamanio_trazo,p.y*tamanio_trazo+tamanio_trazo, this.mP);
			}
		}
		
	}
	
	public MyPunto getCoordenadas(float x, float y){
		int x_ = (int)x/tamanio_celda;
		int y_ = (int)y/tamanio_celda;
		return new MyPunto(x_ , y_);
	}
	
	private void dibujarRec(Canvas c, int x, int y, int color){
		this.mP.setColor(color);
		c.drawRect(x*tamanio_celda,y*tamanio_celda,x*tamanio_celda+tamanio_celda,y*tamanio_celda+tamanio_celda,this.mP);
	}
	
	private boolean esUltimo(Point p){
		int contador=0;
		for(int i=p.x-1; i<=p.x+1; i++){
			for(int j=p.y-1; j<=p.y+1; j++){
				if(Trazo.contains(new Point(i,j))){
					contador++;
				}
			}
		}
		if(contador==2)
			return true;
		else
			return false;
	}

	
	//permite agregar eventos a los widgets de la pantalla.
	public void addListeners(){ 
	   	Btn_salir.setOnClickListener( new View.OnClickListener() {	
				@Override
				public void onClick(View v) {
					finish();
				}
	});
	    
	    Cronometro.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
			@Override
			public void onChronometerTick(Chronometer chronometer) {
				verificarCronometro();
			}
		});
		}
	
		//permite extraer el tiempo del cronometro
	public String getTiempoCronometro(){
		String txt_cronometro= this.Cronometro.getText().toString().substring(9);
		String tiempo[] =  txt_cronometro.split(":");
		return tiempo[1];
	}
		
		//permite verificar si se ha llegado al tiempo limite
	public void verificarCronometro(){
		if(getTiempoCronometro().equalsIgnoreCase(Limite_tiempo) && !this.Reiniciar){
			Reiniciar = true;		
			actualizarContador();
			Intent inten = new Intent(getApplicationContext(),LetraCorrectaActivity.class);
			inten.putExtra("cont",Contador);
			startActivityForResult(inten,SECONDARY_ACTIVITY_REQUEST_CODE);
			if(Contador==4){
				finish();
			}
		}
	}
		
	
	public void actualizarContador(){
		this.Txtcont.setText(Integer.toString(Contador));
		this.Contador++;
	}

		@Override
	public void colorChanged(int color) {
		 mPaint.setColor(color);
	}
		
	private void DibujarCirculos(Canvas c){
		for(Point punto : PuntosLetras){
			c.drawCircle(punto.x,punto.y,6,mCirPaint);
		}
	}
	
		
		
	
		
		//clase view para el canvas
		 public class MyView extends View {

		        //private static final float MINP = 0.25f;
		        //private static final float MAXP = 0.75f;

		        private Bitmap  mBitmap;
		        private Canvas  mCanvas;
		        private Path    mPath;
		        private Paint   mBitmapPaint;
		        private Paint   mCircle;
		        private float mX, mY;
		        private static final float TOUCH_TOLERANCE = 4;		        
		        private Point Anterior = null;
		        
		        

		        public MyView(Context c) {
		            super(c);
		            mPath = new Path();
		            mBitmapPaint = new Paint(Paint.DITHER_FLAG);
		            mCircle = new Paint(mBitmapPaint);
  
		        }

		        @Override
		        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		            super.onSizeChanged(w, h, oldw, oldh);
		            mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
		            mCanvas = new Canvas(mBitmap);
		            dibujarMalla(mCanvas);
		            dibujarTrazo(mCanvas);
		            DibujarCirculos(mCanvas);
		        }

		        @Override
		        protected void onDraw(Canvas canvas) {      	
		            canvas.drawColor(0x8000000);
		            canvas.drawBitmap(mBitmap,0,0, mBitmapPaint);
		            canvas.drawPath(mPath, mPaint);
		        }


		        private void touch_start(float x, float y) {
		            mPath.reset();
		            mPath.moveTo(x, y);
		            mX = x;
		            mY = y;
		        }
		        
		        private void touch_move(float x, float y) {
		            float dx = Math.abs(x - mX);
		            float dy = Math.abs(y - mY);
		            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
		                mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
		                mX = x;
		                mY = y;
		                
		            }
		        }
		        
		        private void touch_up() {
		            mPath.lineTo(mX, mY);
		            // commit the path to our offscreen
		            mCanvas.drawPath(mPath, mPaint);
		            // kill this so we don't double draw
		            mPath.reset();
		        }

		        @Override
		        public boolean onTouchEvent(MotionEvent event) {
		            float x = event.getX();
		            float y = event.getY();

		            switch (event.getAction()) {
		                case MotionEvent.ACTION_DOWN:
		                    touch_start(x, y);
		                    //TxtX.setText(Integer.toString((int)x%tamanio_celda));
							//TxtY.setText(Integer.toString((int)y%tamanio_celda));
		                    invalidate();
		                    break;
		                case MotionEvent.ACTION_MOVE:
		                    touch_move(x, y);
		                    
		                    //guardar las coordenadas del dibujo.
		                    int x_i = (int) mX;
				            int y_i = (int) mY;
							MisPuntos.add(new Point(x_i, y_i));
							
							
							MyPunto p = getCoordenadas(x_i, y_i);
							//TxtX.setText(Integer.toString((int)x%tamanio_celda));
							//TxtY.setText(Integer.toString((int)y%tamanio_celda));
							
							if(Trazo.contains(p)){
								if(Anterior == null){
									Anterior = new Point(p);
								}
								
								if(!Anterior.equals(p)){						
									
									Trazo.indexOf(Anterior);
									Txtcont.setText(Integer.toString(Trazo.indexOf(Anterior)));
									Trazo.get(Trazo.indexOf(Anterior)).setVisitado(true);
									dibujarTrazo(mCanvas);
									DibujarCirculos(mCanvas);
									Anterior.set(p.x,p.y);
								}else{
									if(esUltimo(p) && Anterior!=null){
										dibujarRec(mCanvas,Anterior.x,Anterior.y,Color.GREEN);
									}
								}
							}else{
								TxtY.setText("false");
							}
							
							
		                    invalidate();
		                    break;
		                case MotionEvent.ACTION_UP:
		                    touch_up();
		                   
		                    invalidate();
		                    break;
		            }
		            return true;
		        }
		    }
		 
		//atributos utilizados para el menu al dibujar
		private static final int COLOR_MENU_ID = Menu.FIRST;
		private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
		private static final int BLUR_MENU_ID = Menu.FIRST + 2;
		private static final int ERASE_MENU_ID = Menu.FIRST + 3;
		private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;

		    @Override
		    public boolean onCreateOptionsMenu(Menu menu) {
		        super.onCreateOptionsMenu(menu);

		        menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
		        menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
		        menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
		        menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
		        menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');

		        /****   Is this the mechanism to extend with filter effects?
		        Intent intent = new Intent(null, getIntent().getData());
		        intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
		        menu.addIntentOptions(
		                              Menu.ALTERNATIVE, 0,
		                              new ComponentName(this, NotesList.class),
		                              null, intent, 0, null);
		        *****/
		        return true;
		    }

		    @Override
		    public boolean onPrepareOptionsMenu(Menu menu) {
		        super.onPrepareOptionsMenu(menu);
		        return true;
		    }

		    @Override
		    public boolean onOptionsItemSelected(MenuItem item) {
		        mPaint.setXfermode(null);
		        mPaint.setAlpha(0xFF);

		        switch (item.getItemId()) {
		            case COLOR_MENU_ID:
		                new ColorPickerDialog(this, this, mPaint.getColor()).show();
		                return true;
		            case EMBOSS_MENU_ID:
		                if (mPaint.getMaskFilter() != mEmboss) {
		                    mPaint.setMaskFilter(mEmboss);
		                } else {
		                    mPaint.setMaskFilter(null);
		                }
		                return true;
		            case BLUR_MENU_ID:
		                if (mPaint.getMaskFilter() != mBlur) {
		                    mPaint.setMaskFilter(mBlur);
		                } else {
		                    mPaint.setMaskFilter(null);
		                }
		                return true;
		            case ERASE_MENU_ID:
		                mPaint.setXfermode(new PorterDuffXfermode(
		                                                        PorterDuff.Mode.CLEAR));
		                return true;
		            case SRCATOP_MENU_ID:
		                mPaint.setXfermode(new PorterDuffXfermode(
		                                                    PorterDuff.Mode.SRC_ATOP));
		                mPaint.setAlpha(0x80);
		                return true;
		        }
		        return super.onOptionsItemSelected(item);
		    }
		
		
}
